package com.lv.utils.variableTask;

import com.lv.utils.mapper.CronMysqlMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronSequenceGenerator;
import org.springframework.scheduling.support.CronTrigger;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * @author: Lv_sc
 * Date:     2021/3/26 17:56
 * Description: 可变定时任务  cron表达式从数据库中获取
 * 缺点 ：1.不回立刻生效 比如当前定义1个小时后执行，更改后当前一个小时要执行完成，才会重新加载  解决：理解生效型
 * 2.当corn表达式是错误的时候，任务失败并且停止，重启需要重启服务。   解决：校验corn表达式
 */
@Configuration
@EnableScheduling
public class VariableTask implements SchedulingConfigurer {

    private final static Logger logger = LoggerFactory.getLogger(VariableTask.class);
    private final static String CRON = "0/10 * * * * ?";

    @Resource
    CronMysqlMapper cronMapper;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> {
                    logger.error("可变定时任务时间: {}", LocalDateTime.now());
                    logger.info("业务逻辑");
                },

                //2.设置执行周期(Trigger)
                triggerContext -> {
                    //2.1 从数据库获取执行周期
                    String cron = cronMapper.getCron().getCron();
                    //2.2 合法性校验.防止定时任务停止
                    if (!CronSequenceGenerator.isValidExpression(cron)) {
                        //如果当前cron不正确，替换默认
                        cron = CRON;
                    }
                    //2.3 返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }
}